package com.sunshine.wrongquestionset.room.entity

import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.Index
import androidx.room.PrimaryKey

/**
 * @author sunshine
 * @date 2021/3/26
 * 题目表实体类
 * @see UserEntity 外键 用户id
 * @see SubjectEntity 外键 题目的科目
 * @see QuestionTypeEntity 外键 题目的类型
 */
@Entity(
    tableName = "question",
    foreignKeys = [
        ForeignKey(
            entity = QuestionSetEntity::class,
            parentColumns = ["id"],
            childColumns = ["questionSetId"],
            onUpdate = ForeignKey.CASCADE,
            onDelete = ForeignKey.CASCADE
        ),
        ForeignKey(
            entity = UserEntity::class,
            parentColumns = ["id"],
            childColumns = ["userId"],
            onUpdate = ForeignKey.CASCADE,
            onDelete = ForeignKey.CASCADE
        ),
        ForeignKey(
            entity = QuestionTypeEntity::class,
            parentColumns = ["id"],
            childColumns = ["typeId"],
            onDelete = ForeignKey.SET_DEFAULT,
            onUpdate = ForeignKey.CASCADE
        ),
        ForeignKey(
            entity = SubjectEntity::class,
            parentColumns = ["id"],
            childColumns = ["subjectId"],
            onDelete = ForeignKey.CASCADE,
            onUpdate = ForeignKey.CASCADE
        )
    ],
    indices = [
        Index("questionSetId"),
        Index("userId"),
        Index("typeId"),
        Index("subjectId")
    ]
)
class QuestionEntity(
    @PrimaryKey(autoGenerate = true)
    val id: Int,
    //用户id
    val userId: String,
    //错题集id
    val questionSetId: Int,

    //2021 04 10更新：今天更变了逻辑：科目下属错题本，所以题目中不需要记录科目id
    //2021 04 14更新：又加回来的，要不读取某科目的题目太费劲了
    //默认值为-1，表示未知科目
    val subjectId: Int = -1,

    val typeId: Int = -1,
    //TODO 暂时采用这种方法来存储标签，但是可能导致后期查找有问题，采用#来分割标签
    val tag: String,
    //存放题目的文件路径，因为现在设想为采用md文件存放题目
    val titlePath: String,
    val answerPath: String,

    //2021/04/10更新：将熟悉程度移动到每一次做题，这样可以显示变化周期
    //2021 04 11更新：错题的熟悉程度保留，但是这里的仍然需要一个最新的熟悉程度，这样调用时比较方便
    //对题目的熟悉程度，这里采用浮点数进行表示
    var familiarity: Float,

    //题目难度，采用浮点数进行表示
    val difficulty: Float,

    //2021/04/10更新：为了遗忘曲线分析
    //上一次做这道题的时间
    var lastTime: Long,
    //到目前位置一共做了几次
    var doCount: Int = 0,

    //2021 04 10更新 新增笔记列
    val note: String?,

    //2021 04 11更新 添加这道题目的时间，用来判断遗忘曲线天数
    var insertTime: Long,

    //2021 04 12更新，添加题目分数，用来后期判断熟悉程度增加情况
    var score: Float
) {


    companion object {
        const val FAMILIARITY_MAX = 1.0f
        const val FAMILIARITY_MIN = 0.0f
    }

    override fun toString(): String {
        return "QuestionEntity(id=$id, userId='$userId', questionSetId=$questionSetId, typeId=$typeId, tag='$tag', titlePath='$titlePath', answerPath='$answerPath', familiarity=$familiarity, difficulty=$difficulty, lastTime=$lastTime, doCount=$doCount, note=$note, insertTime=$insertTime, score=$score)"
    }

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false

        other as QuestionEntity

        if (id != other.id) return false
        if (userId != other.userId) return false
        if (questionSetId != other.questionSetId) return false
        if (subjectId != other.subjectId) return false
        if (typeId != other.typeId) return false
        if (tag != other.tag) return false
        if (titlePath != other.titlePath) return false
        if (answerPath != other.answerPath) return false
        if (familiarity != other.familiarity) return false
        if (difficulty != other.difficulty) return false
        if (lastTime != other.lastTime) return false
        if (doCount != other.doCount) return false
        if (note != other.note) return false
        if (insertTime != other.insertTime) return false
        if (score != other.score) return false

        return true
    }

    override fun hashCode(): Int {
        var result = id
        result = 31 * result + userId.hashCode()
        result = 31 * result + questionSetId
        result = 31 * result + subjectId
        result = 31 * result + typeId
        result = 31 * result + tag.hashCode()
        result = 31 * result + titlePath.hashCode()
        result = 31 * result + answerPath.hashCode()
        result = 31 * result + familiarity.hashCode()
        result = 31 * result + difficulty.hashCode()
        result = 31 * result + lastTime.hashCode()
        result = 31 * result + doCount
        result = 31 * result + (note?.hashCode() ?: 0)
        result = 31 * result + insertTime.hashCode()
        result = 31 * result + score.hashCode()
        return result
    }


}
